package com.mes.handler.plan;

import com.basis.utils.CodeGenerateRuleUtil;
import com.basis.utils.HibernateDao;
import com.eam.data.EamFacilities;
import com.mes.data.EmesColor;
import com.mes.data.EmesComponent;
import com.mes.data.EmesProcess;
import com.mes.data.EmesShape;
import com.mes.manufacture.data.EmesoJobOrder;
import com.mes.manufacture.data.EmesoJobOrderExe;
import com.mes.manufacture.data.EmesoJobOrderMaterial;
import com.mes.manufacture.data.EmesoManuOrder;
import com.mes.utils.EmesoMOJobOrderUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;
import org.openbravo.client.kernel.BaseActionHandler;
import org.openbravo.dal.core.OBContext;
import org.openbravo.dal.service.OBDal;
import org.openbravo.model.common.plm.Product;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 作业下发，派工
 */
public class JobOrderAssignHandler extends BaseActionHandler {
	@Override
	protected JSONObject execute(Map<String, Object> parameters, String data) {
		JSONObject jsonRep = new JSONObject();
		try {
			//设置最高权限
			OBContext.setAdminMode();
			JSONObject reqData = new JSONObject(data);

			String type = reqData.getString("type");

			if ("submit".equalsIgnoreCase(type)) {
				String[] nums = reqData.getString("nums").split(",");
				String facId = reqData.getString("facId");
				String description = reqData.isNull("description") ? null : reqData.getString("description");
				String[] ids = reqData.getString("orderIds").split(",");

				assignToFacilities(ids, facId, description, nums);
				//回写状态
				EmesoMOJobOrderUtils.syncUpdateOrderStatus();

				OBDal.getInstance().commitAndClose();

				jsonRep.put("result", true);
				jsonRep.put("msg", "派工成功！");
			} else if ("orders".equalsIgnoreCase(type)) {
				String facId = reqData.getString("facId");
				jsonRep.put("result", true);
				jsonRep.put("list", this.getJobOrderList(facId));
				jsonRep.put("msg", "查询飞织列表成功！");
			} else if ("del".equalsIgnoreCase(type)) {//删除已派工工单
				String []jobOrders = reqData.getString("jobOrders").split(",");
				deleteJobOrder(jobOrders);
				jsonRep.put("result", true);
				jsonRep.put("msg", "删除成功！");

				OBDal.getInstance().commitAndClose();
			} else if ("oneKey".equalsIgnoreCase(type)) {//一键派工
				String[] ids = reqData.getString("ids").split(",");
				String strIds = new ManuOrderGenerateTimeHandler().onKeyAssign(getOrderList(ids));
				jsonRep.put("ids", strIds);
				jsonRep.put("result", true);
				jsonRep.put("msg", "一键派工完成！");
			} else {//查询订单列表
				String[] ids = reqData.getString("ids").split(",");
				jsonRep.put("result", true);
				jsonRep.put("facList", getFzList());
				jsonRep.put("orderList", toJsonArray(getOrderList(ids)));
			}
		} catch (Exception e) {
			e.printStackTrace();
			OBDal.getInstance().rollbackAndClose();
			try {
				jsonRep.put("result", false);
				if (e.getCause() != null) {
					jsonRep.put("msg", e.getCause().getMessage());
				} else {
					jsonRep.put("msg", e.getMessage());
				}
			} catch (Exception ex) {
			}
		} finally {
			OBContext.restorePreviousMode();
		}
		return jsonRep;
	}

	/**
	 * 派工到飞织机
	 * @param ids
	 */
	private void assignToFacilities(String[] ids, String facId, String description, String[] nums) {
		for (int i = 0; i < ids.length; i++) {
			assignToFacilities(ids[i], facId, description, Double.valueOf(nums[i]).intValue());
		}
	}

	/**
	 * 派工到飞织机
	 * @param id
	 */
	public void assignToFacilities(String id, String facId, String description, int num) {
		EmesoManuOrder emo = OBDal.getInstance().get(EmesoManuOrder.class, id);
		int qty = emo.getQty().intValue();
		int qtyAssign = 0;
		if (emo.getQtyAssign() != null && !emo.getQtyAssign().equals("") && !emo.getQtyAssign().equals("null")) {
			qtyAssign = emo.getQtyAssign().intValue();
		}
		if (num + qtyAssign == qty) {
			emo.setStatus("ISSUED");
		} else {
			emo.setStatus("EXECUTING");
		}
		emo.setQtyAssign(new BigDecimal(num + qtyAssign));
		OBDal.getInstance().save(emo);
		//生成作业订单
		createJobOrder(emo, facId, description, num);

		String sql = "update Emeso_ManuOrder set status = 'ISSUED' where qty = qty_assign and status in ('CREATE', 'EXECUTING')";
		HibernateDao.executeSql(sql);
	}

	//同步生成
	private void createJobOrder(EmesoManuOrder emo, String facId, String description, int qty) {
		EmesoJobOrder jobOrder = null;
		for (int i = 0; i < qty; i++) {
			jobOrder = new EmesoJobOrder();
			String code = CodeGenerateRuleUtil.getCode("Emeso_Job_Order", "code");

			jobOrder.setProduct(emo.getProduct());
			jobOrder.setCode(code);
			jobOrder.setQty(1l);
			jobOrder.setEmesoManuorder(emo);
			jobOrder.setStatus("CREATE");
			jobOrder.setDescription(emo.getDescription() + " " + description);

			//根据小时级计划，计算预计开工时间

			OBDal.getInstance().save(jobOrder);

			createJobOrderExe(emo, jobOrder, facId);

			addMaterial(jobOrder, emo);
		}
	}

	private void createJobOrderExe(EmesoManuOrder emo, EmesoJobOrder jobOrder, String facId) {
		String sql = "select Emes_Process_id from Emeso_ManuOrder_Process where  Emeso_ManuOrder_Id = ? ";
		List<Map<String, Object>> processList = HibernateDao.query(sql, emo.getId());
		if (processList == null || processList.isEmpty()) {
			throw new RuntimeException("当前形体[" + emo.getProduct().getSearchKey() + " - " + emo.getProduct().getName() + "]未配置有效工艺路线！");
		}

		EmesProcess process = null;
		EmesoJobOrderExe jobExe = null;
		for (Map<String, Object> map : processList) {
			process = (EmesProcess) OBDal.getInstance().get(EmesProcess.ENTITY_NAME, map.get("EMES_PROCESS_ID"));

			jobExe = new EmesoJobOrderExe();
			if (process.getName().indexOf("飞织") > -1) {
				jobExe.setEamFacilities((EamFacilities) OBDal.getInstance().get(EamFacilities.ENTITY_NAME, facId));
			}
			jobExe.setEmesProcess(process);
			jobExe.setRouteName(process.getName());
			jobExe.setRouteNo(process.getRouteNo());
			jobExe.setEmesoJobOrder(jobOrder);

			OBDal.getInstance().save(jobExe);
		}
	}

	/**
	 * 添加作业工单辅料列表
	 *
	 * @param jobOrder
	 */
	private void addMaterial(EmesoJobOrder jobOrder, EmesoManuOrder order) {
		String sql = " select sc.m_product_id as WLID , bom.emes_color_id as YSID, bom.emes_shape_id as XZID , bom.emes_component_id as BWID  " +
				" from emeso_manuorder sc , emeso_manuorder_bom bom   " +
				" where sc.emeso_manuorder_id = bom.emeso_manuorder_id  " +
				" and bom.emes_shape_id is not null  " +
				" and bom.emes_component_id is not null  " +
				" and sc.emeso_manuorder_id =  '" + order.getId() + "'";
		List<Map<String, Object>> result = HibernateDao.query(sql);
		EmesoJobOrderMaterial jobMaterial = null;

		for (Map<String, Object> map : result) {
			jobMaterial = new EmesoJobOrderMaterial();

			jobMaterial.setEmesColor(OBDal.getInstance().get(EmesColor.class, map.get("YSID")));
			jobMaterial.setEmesoJobOrder(jobOrder);
			jobMaterial.setEmesShape(OBDal.getInstance().get(EmesShape.class, map.get("XZID")));
			jobMaterial.setEmesComponent(OBDal.getInstance().get(EmesComponent.class, map.get("BWID")));
			jobMaterial.setProduct(OBDal.getInstance().get(Product.class, map.get("WLID")));
			jobMaterial.setStatus("CREATE");

			OBDal.getInstance().save(jobMaterial);
		}
	}

	/**
	 * 获取飞织列表
	 */
	public List<JSONObject> getFzList() {
		String sql = "select eam_facilities_id id, code, name, status, nvl(run_status, 'RUN') run_status," +
				"(select count(*) from emeso_job_order_exe joe where joe.status = 'CREATE' " +
				"	and joe.eam_facilities_id = f.eam_facilities_id) count0 " +
				" from eam_facilities f where facility_type = 'FZJ' order by code";
		List<Map<String, Object>> result = HibernateDao.query(sql);
		List<JSONObject> list = new ArrayList();
		JSONObject json = null;
		for (Map<String, Object> map : result) {
			try {
				json = new JSONObject();
				json.put("id", map.get("ID"));
				json.put("code", map.get("code"));
				json.put("name", map.get("name"));
				json.put("count", map.get("count0"));
				json.put("status", map.get("status"));
				json.put("run_status", map.get("run_status"));
				json.put("colors", getFzTypeModel((String) map.get("id")));

				list.add(json);
			} catch (Exception e) {
			}
		}
		return list;
	}

	/**
	 * 获取飞织机对应的形体、颜色
	 */
	private JSONArray getFzTypeModel(String facId) {
		String sql = "select p.value pcode, p.name pname, pi.code, pi.name\n" +
				"  from m_product p, emes_pbom_item pi, eam_facilities_color fc \n" +
				" where p.m_product_id = fc.m_product_id\n" +
				"   and pi.emes_pbom_item_id = fc.emes_pbom_item_id\n" +
				"   and fc.eam_facilities_id = ?" +
				" order by p.value, pi.seqno";
		List<Map<String, Object>> result = HibernateDao.query(sql, facId);
		JSONArray list = new JSONArray();
		JSONObject json = null;
		for (Map<String, Object> map : result) {
			try {
				json = new JSONObject();
				json.put("pcode", map.get("pcode"));
				json.put("pname", map.get("pname"));
				json.put("code", map.get("code"));
				json.put("name", map.get("name"));

				list.put(json);
			} catch (Exception e) {
			}
		}
		return list;
	}

	/**
	 * 获取工单列表
	 */
	private List getOrderList(String[] ids) {
		String sql = " SELECT sc.emeso_manuorder_id ID, sc.code, " +
				"	wl.VALUE pCode, wl.NAME pName, sc.qty, sc.foot_size_code, " +
				"	COALESCE (sc.qty_assign, 0) AS qtyassign, (sc.qty - COALESCE(sc.qty_assign, 0)) AS qtys," +
				"	(select color from emesp_planorder po where po.emesp_planorder_id = sc.emesp_planorder_id) color " +
				"  FROM emeso_manuorder sc, m_product wl " +
				" WHERE sc.m_product_id = wl.m_product_id " +
				"	and sc.status in ('CREATE', 'EXECUTING')" +
				"	AND sc.emeso_manuorder_id in (''";
		for (String id : ids) {
			sql += ", ?";
		}
		sql += ")";
		return HibernateDao.query(sql, ids);
	}

	/**
	 * 将数据转换为Json对象列表
	 */
	private List toJsonArray(List<Map<String, Object>> result) {
		List<JSONObject> list = new ArrayList();
		JSONObject json = null;
		for (Map<String, Object> map : result) {
			try {
				json = new JSONObject();
				json.put("id", map.get("ID"));
				json.put("code", map.get("code"));
				json.put("pCode", map.get("pCode"));
				json.put("pName", map.get("pName"));
				json.put("qty", map.get("qty"));

				json.put("oldqty", map.get("qtyassign"));
				json.put("qtys", map.get("qtys"));

				json.put("size", map.get("foot_size_code"));
				json.put("color", map.get("color"));

				list.add(json);
			} catch (Exception e) {
			}
		}
		return list;
	}
	/**
	 * 获取工单列表
	 */
	private List getJobOrderList(String facId) {
		String sql = "select o.emeso_job_order_id id, o.code, oe.status, mo.foot_size_code, mo.code moCode, nvl(oe.is_assistant, '') xfStatus, " +
				"	(select color from emesp_planorder po where po.emesp_planorder_id = mo.emesp_planorder_id) color " +
				"  from emeso_manuorder mo, emeso_job_order o, Emeso_Job_Order_Exe oe\n" +
				" where mo.emeso_manuorder_id = o.emeso_manuorder_id" +
				"   and oe.emeso_job_order_id = o.emeso_job_order_id\n" +
				"   and oe.status = 'CREATE'\n " +
				//"	and nvl(oe.is_assistant, '') <> 'Y'" +//为下发到飞织机
				"	and oe.Eam_Facilities_ID = ?";
		List<Map<String, Object>> result = HibernateDao.query(sql, facId);
		List<JSONObject> list = new ArrayList();
		JSONObject json = null;
		for (Map<String, Object> map : result) {
			try {
				json = new JSONObject();
				json.put("id", map.get("ID"));
				json.put("code", map.get("code"));
				json.put("moCode", map.get("moCode"));
				json.put("fzj", map.get("fzj"));
				json.put("xfStatus", map.get("xfStatus"));
				json.put("size", map.get("foot_size_code"));
				json.put("color", map.get("color"));

				list.add(json);
			} catch (Exception e) {
			}
		}
		return list;
	}
	/**
	 * 删除飞织任务
	 */
	private void deleteJobOrder(String[] ids) {
		String delExe = "delete from emeso_job_order_exe where emeso_job_order_id = ?";
		String delJob = "delete from emeso_job_order where emeso_job_order_id = ?";
		String delMateril = "delete from emeso_job_order_material where emeso_job_order_id = ?";
		String update = "update emeso_manuorder set qty_assign = qty_assign - 1, status = 'EXECUTING' where qty_assign > 0 and emeso_manuorder_id = ?";

		for (String id : ids) {
			String manuId = checkJobOrderStatus(id);

			//将对于拉动计划状态修改，还回已派工数量，状态修改为部分派工
			HibernateDao.executeSql(update, manuId);

			//删除对于的作业工单工序，工单信息，裁断辅料明细
			HibernateDao.executeSql(delExe, id);
			HibernateDao.executeSql(delMateril, id);
			HibernateDao.executeSql(delJob, id);
		}

		//修改状态与数量不匹配数据
		HibernateDao.executeSql("update emeso_manuorder \n" +
				"   set status = (case when qty_assign = 0 then 'CREATE' else 'EXECUTING' end)\n" +
				" where nvl(qty_assign, 0) < qty and status in ('ISSUED', 'EXECUTING')");
	}

	/**
	 * 验证作业工单的状态
	 * @return
	 */
	private String checkJobOrderStatus(String id) {
		String checkSql = "select jo.status, joe.status jStatus, nvl(joe.is_assistant, '') xfStatus, jo.code, jo.emeso_manuorder_id " +
				"  from emeso_job_order_exe joe, emeso_job_order jo " +
				" where joe.emeso_job_order_id = jo.emeso_job_order_id " +
				"	and jo.emeso_job_order_id = ?";
		Map<String, Object> map = HibernateDao.queryUnique(checkSql, id);
		if (map != null) {
			if (!"CREATE".equals(map.get("status"))) {
				throw new RuntimeException("作业工单【" + map.get("code") + "】已无法删除，状态不等于待开工状态！");
			}
			if ("Y".equals(map.get("xfStatus"))) {
				throw new RuntimeException("作业工单【" + map.get("code") + "】已无法删除，任务已下发到飞织机！");
			}
			return (String)map.get("emeso_manuorder_id");
		} else {
			throw new RuntimeException("传入的作业工单ID错误");
		}
	}
}
